import os
import subprocess
import datetime
import time
import subprocess
import psutil
from notebook.auth import passwd
import argparse
import shutil
from multiprocessing import Process
import sys
timeout = 1000
user_config_str = "c.NotebookApp.notebook_dir = \'{Path}\'"+"\n"+"c.NotebookApp.token = \'{hashed}\'"+"\n"+"c.NotebookApp.port = {port}"
contextList = ["c.NotebookApp.token = u\'{hashed}\'"+"\n","c.NotebookApp.port = {port}"]
command_str = "jupyter notebook --config {configfile}"
#文件路径#
file_base = "F:\\workspace\\hj\\python\\"
#file_base = "C:\\Users\\98657\\Desktop\\722\\"

#文件#
pythonfile1 = file_base+"clean.ipynb" 
pythonfile2 = file_base+"ML.ipynb"
pythonfile3 = file_base+"Train.ipynb"
config  = "config.py"
dict_wine = file_base+"wine_bottles.txt"
wine1 = file_base+"微博红酒.csv"
wine2 = file_base+"红酒品牌.csv"
wine3 = file_base+"电商红酒.csv"

#路径#
base = "F:\\workspace\\hj\\python\\users\\"
tree_base = "F:\\\\workspace\\\\hj\\\\python\\\\users\\\\"
#base = "C:\\Users\\98657\\Desktop\\722\\users\\"
#tree_base = "C:\\\\Users\\\\98657\\\\Desktop\\\\722\\\\users\\\\"

user_config_path = base+"{user}\\config.py"
user_file_path = base+"{user}"
tree_formart = tree_base+"{user}\\\\tree"

strr = ""

        

def update_config(user,context,index):        #return status    index = 1 ←port  index  = 0 ←token
     uConfigStr = user_config_path.format(user = user)
     #print("port : {p}}".format(p = context))
     try:
       lines = open(uConfigStr, 'r').readlines()
       if index == 1:
        lines[index-2]=contextList[index].format(port = context)
       else:
        lines[index-2]=contextList[index].format(hashed = passwd(context))
       open(uConfigStr, 'w').writelines(lines)
       return True
     except:
       s = "update {user} config file failed".format(user = user)
       #print(s)
       return False 

def getpid(port):  
    port = int(port)                           #return current pid
    net_con = psutil.net_connections()
    pid = 0
    for e in net_con:
        if int(e.laddr.port) == port:
            pid=e.pid
            return pid
            #break
    return pid

def search_port():                   #return free port
    ports = range(8888,9999)
    newport=0
    for e in ports:
        idd = getpid(e)
        if idd == 0:
          newport = e
          #print(newport)
          #print(newport)
          return newport
    return newport    

def create_user_jupyter(user,pwd):       #return 1.status  2.port
   hashed = passwd(pwd)
   #print("create_user_jupyter")
   #print("??   "+hashed)
   try:
     hashed = hashed.split("sha1:")[1]
   except:
     hashed = hashed.split("p=")[1]
   #print("??"+hashed)
   path = user_file_path.format(user = user)
   tree = tree_formart.format(user = user)
   port = search_port()
   try:
    
    os.mkdir(path)
    
    strf = file_base+config
    shutil.copy(strf,path)
    #print("@12")
    configPath = path+"\\"+config
    os.mkdir(path+"\\"+"tree")
    os.mkdir(path+"\\"+"tree"+"\\dict")
    os.mkdir(path+"\\"+"tree"+"\\data")
    d = path+"\\"+"tree"+"\\dict"
    data = path+"\\"+"tree"+"\\data"
    shutil.copy(pythonfile1,tree)
    shutil.copy(pythonfile2,tree)
    shutil.copy(pythonfile3,tree)
    #shutil.copy(dict_wine,tree)
    shutil.copy(dict_wine, d)
    shutil.copy(wine1, data)
    shutil.copy(wine2, data)
    shutil.copy(wine3, data)
    s = user_config_str.format(Path=tree,port=port,hashed=hashed,token=hashed)
    
    with open(configPath, 'a') as f:
      f.write(s)
      #print("@12")
   except OSError as err:
     print("OS error: {0}".format(err))
     return False,port,hashed
   return True,port,hashed
   
def get_user_singed_port(user):               #return user's port
     path = user_config_path.format(user=user)
     #print("?")
     lines = open(path, 'r').readlines()
     p=lines[-1].split(" = ")
     #print("?????"+str(p))     
     return p[1]   

def get_user_hashed(user):               #return user's port
     path = user_config_path.format(user=user)
     #print("?")
     lines = open(path, 'r').readlines()
     p=lines[-2].split(" = ")
     #print("?????"+str(p))     
     return p[1][1:-2]         
      
def shutdown(user,port):
  try:
     pid = getpid(port)
     #print(pid)     
     while pid != 0:    
       process = psutil.Process(pid)
       process.terminate()
       time.sleep(0.1)
       pid = getpid(port)
       #print(pid)
     path =  user_file_path.format(user = user)
     shutil.rmtree(path)
     print('True')
  except:
     print('False')   
      
      
#################################

#           Main

#################################
def run_session(user,pwd,choice):  
    #print(user)     
    #check user path exists
    dirs = user_file_path.format(user = user)
    #print(user)
    
    if int(choice)== 0:
       try: 
         port = get_user_singed_port(user)
       #print(port)
         shutdown(user,int(port))
         return
       except:
          print('False')
          return
    if not os.path.exists(dirs)and int(choice) ==1:
       #创建用户
       c,port,hashed = create_user_jupyter(user,pwd)
       if not c :
         #print("创建用户：{user}失败".format(user = user))
         return
       #print("创建用户：{user}成功, 端口号：{port}".format(user = user, port = port))
       port = get_user_singed_port(user)
       sta = getpid(port)
       while sta != 0 :
          port = search_port()
          # update port
          if update_config(user,port,1):
            s = "update {user} port:{port} ".format(user = user,port = port)
            #print(s)
            sta = getpid(port)
       
       #print(command)
       port = int(get_user_singed_port(user))
       #print(port)
       #time.sleep(20)
       systemcommand = "python {path}t3.py -timeout {timeout} -user {user} -port {port}".format(timeout=timeout,user=user,port=port,path=file_base)
       
       ping = subprocess.Popen(systemcommand, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
       #print(port)
       #os.system(systemcommand)
       pid = 0
       t = (port%10) / 10
       while pid==0:
         #print(t)
         time.sleep(0.1+t)
         pid = getpid(port)
       s = "{port}#{hashed}".format(user=user,port=port,hashed=hashed)
       #strr = s
       print(s)             
    else:
        #s = "user:{user} exsits".format(user = user)
        try:
          port = get_user_singed_port(user)
          hashed = get_user_hashed(user)
          s = "{port}#{hashed}".format(user=user,port=port,hashed=hashed)
          #print("logging")
          print(s)
        except:
          path =  user_file_path.format(user = user)
          shutil.rmtree(path)
          print("重新请求一次")
    #return strr    
        
         
        
     
  


if __name__ == '__main__':
    #print(sys.argv[1])
    run_session(sys.argv[1],sys.argv[2],sys.argv[3])
